import redis


class RedisOperator:
    def __init__(self, host='10.86.3.113', port=6379, db=0, password="123456"):
        """
        初始化 Redis 连接
        :param host: Redis 服务器地址
        :param port: Redis 服务器端口
        :param db: 要使用的 Redis 数据库编号
        :param password: Redis 服务器密码
        """
        try:
            self.redis_client = redis.Redis(
                host=host,
                port=port,
                db=db,
                password=password,
                decode_responses=True
            )
            # 测试连接
            self.redis_client.ping()
        except redis.exceptions.ConnectionError as e:
            print(f"连接 Redis 服务器时出错: {e}")
        except redis.exceptions.AuthenticationError as e:
            print(f"Redis 认证失败: {e}")

    def set_key(self, key, value, ex=None):
        """
        设置键值对
        :param key: 键
        :param value: 值
        :param ex: 过期时间（秒）
        :return: 设置成功返回 True，失败返回 False
        """
        try:
            return self.redis_client.set(key, value, ex=ex)
        except redis.exceptions.RedisError as e:
            print(f"设置键值对时出错: {e}")
            return False
        finally:
            self.redis_client.close()

    def get_key(self, key):
        """
        获取键对应的值
        :param key: 键
        :return: 键对应的值，如果键不存在返回 None
        """
        try:
            return self.redis_client.get(key)
        except redis.exceptions.RedisError as e:
            print(f"获取键值时出错: {e}")
            return None
        finally:
            self.redis_client.close()

    def delete_key(self, key):
        """
        删除键
        :param key: 键
        :return: 删除成功返回删除的键的数量，失败返回 0
        """
        try:
            return self.redis_client.delete(key)
        except redis.exceptions.RedisError as e:
            print(f"删除键时出错: {e}")
            return 0
        finally:
            self.redis_client.close()

    def set_expire(self, key, seconds):
        """
        为键设置过期时间
        :param key: 键
        :param seconds: 过期时间（秒）
        :return: 设置成功返回 True，失败返回 False
        """
        try:
            return self.redis_client.expire(key, seconds)
        except redis.exceptions.RedisError as e:
            print(f"设置过期时间时出错: {e}")
            return False
        finally:
            self.redis_client.close()

    def hset(self, name, key=None, value=None, mapping=None):
        """
        设置哈希字段值
        :param name: 哈希表名
        :param key: 字段名
        :param value: 字段值
        :param mapping: 字典形式的多个字段值
        :return: 新增字段数量
        """
        try:
            if mapping:
                return self.redis_client.hset(name, mapping=mapping)
            return self.redis_client.hset(name, key, value)
        except redis.exceptions.RedisError as e:
            print(f"设置哈希字段时出错: {e}")
            return 0

    def hget(self, name, key):
        """
        获取哈希字段值
        :param name: 哈希表名
        :param key: 字段名
        :return: 字段值
        """
        try:
            return self.redis_client.hget(name, key)
        except redis.exceptions.RedisError as e:
            print(f"获取哈希字段时出错: {e}")
            return None

    def hgetall(self, name):
        """
        获取哈希表所有字段和值
        :param name: 哈希表名
        :return: 字典形式的字段和值
        """
        try:
            return self.redis_client.hgetall(name)
        except redis.exceptions.RedisError as e:
            print(f"获取哈希表所有字段时出错: {e}")
            return {}

    def hdel(self, name, *keys):
        """
        删除哈希表一个或多个字段
        :param name: 哈希表名
        :param keys: 要删除的字段名
        :return: 删除的字段数量
        """
        try:
            return self.redis_client.hdel(name, *keys)
        except redis.exceptions.RedisError as e:
            print(f"删除哈希字段时出错: {e}")
            return 0


if __name__ == "__main__":
    # 使用示例
    redis_op = RedisOperator()
    redis_op.hset('/v1/charge/cid', mapping={"status_type": 1, "timeout": 2, "time_count": 0, "error_count": 0})
    redis_op.hset('/v2/schedule', mapping={"status_type": 1, "timeout": 2, "time_count": 0, "error_count": 0})
    redis_op.hset('/v1/aapmgr/POST', mapping={"status_type": 1, "timeout": 2, "time_count": 0, "error_count": 0})
    redis_op.hset('/v1/aapmgr/GET', mapping={"status_type": 1, "timeout": 6, "time_count": 0, "error_count": 0})
    redis_op.hset('/v1/charge/stop', mapping={"status_type": 1, "timeout": 5, "time_count": 0, "error_count": 0})
    redis_op.hset('/v1/aapmgr/DELETE', mapping={"status_type": 1, "timeout": 6, "time_count": 0, "error_count": 0})
    redis_op.hset('/v2/release', mapping={"status_type": 1, "timeout": 6, "time_count": 0, "error_count": 0})
